package com.roundarch.flex.controls.graphControlClasses
{
    import com.roundarch.flex.controls.GraphControlBase;
    import com.roundarch.flex.controls.graphControlInterfaces.IGraphControlChild;
    import com.roundarch.flex.controls.graphControlInterfaces.IGraphControlRenderer;
    import com.roundarch.flex.controls.graphControlInterfaces.IInterval;
    import com.roundarch.flex.controls.graphControlInterfaces.IIntervalCollection;
    import com.roundarch.flex.controls.graphControlInterfaces.IIntervalToStringGenerator;

    import flash.display.BitmapData;
    import flash.events.Event;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;

    import mx.core.BitmapAsset;
    import mx.core.UIComponent;
    import mx.core.UITextField;

    //-----------------------------
    //  Styles
    //-----------------------------
    [Style(name = "fontStyle", type = "String", enumeration = "normal,italic", inherit = "yes")]
    [Style(name = "fontSize", type = "Number", format = "Length", inherit = "yes")]
    [Style(name = "fontFamily", type = "String", inherit = "yes")]
    [Style(name = "color", type = "uint", format = "Color", inherit = "yes")]
    [Style(name = "fontWeight", type = "String", enumeration = "normal,bold", inherit = "yes")]
    [Style(name = "kerning", type = "Boolean", inherit = "yes")]
    [Style(name = "letterSpacing", type = "Number", inherit = "yes")]
    [Style(name = "textDecoration", type = "String", enumeration = "none,underline", inherit = "yes")]

    /**
     *
     * @author Josh
     */
    public class GraphControlLabelRenderer extends UIComponent implements IGraphControlRenderer
    {
        //---------------------------------------------------------------------
        //
        //  Variables
        //
        //---------------------------------------------------------------------
        protected var helperTextField : UITextField;
        protected var bitmap : BitmapAsset;

        //---------------------------------------------------------------------
        //
        //  Properties
        //
        //---------------------------------------------------------------------
        //-----------------------------
        // direction
        //-----------------------------
        /**
         * @private
         */
        protected var _direction : String = "horizontal";

        [Bindable("directionChanged")]
        /**
         *
         *
         * @default "horizontal"
         */
        public function get direction() : String
        {
            return _direction;
        }

        /**
         * @private
         */
        public function set direction(value : String) : void
        {
            if (value == _direction)
            {
                return;
            }

            _direction = value;

            dispatchEvent(new Event("directionChanged"));
        }

        //-----------------------------
        // intervalCollection
        //-----------------------------
        /**
         * @private
         */
        protected var _intervalCollection : IIntervalCollection = null;

        [Bindable("intervalCollectionChanged")]
        /**
         *
         *
         * @default null
         */
        public function get intervalCollection() : IIntervalCollection
        {
            return _intervalCollection;
        }

        /**
         * @private
         */
        public function set intervalCollection(value : IIntervalCollection) : void
        {
            if (value == _intervalCollection)
            {
                return;
            }

            _intervalCollection = value;

            dispatchEvent(new Event("intervalCollectionChanged"));
        }

        //-----------------------------
        // intervalToStringGenerator
        //-----------------------------
        /**
         * @private
         */
        protected var _intervalToStringGenerator : IIntervalToStringGenerator = null;

        [Bindable("intervalToStringGeneratorChanged")]
        /**
         *
         *
         * @default null
         */
        public function get intervalToStringGenerator() : IIntervalToStringGenerator
        {
            return _intervalToStringGenerator;
        }

        /**
         * @private
         */
        public function set intervalToStringGenerator(value : IIntervalToStringGenerator) : void
        {
            if (value == _intervalToStringGenerator)
            {
                return;
            }

            _intervalToStringGenerator = value;

            dispatchEvent(new Event("intervalToStringGeneratorChanged"));
        }

        //-----------------------------
        // parentGC
        //-----------------------------
        /**
         * @private
         */
        protected var _parentGC : GraphControlBase = null;

        [Bindable("parentGCChanged")]
        /**
         *
         *
         * @default null
         */
        public function get parentGC() : GraphControlBase
        {
            return _parentGC;
        }

        /**
         * @private
         */
        public function set parentGC(value : GraphControlBase) : void
        {
            if (value == _parentGC)
            {
                return;
            }

            _parentGC = value;

            dispatchEvent(new Event("parentGCChanged"));
        }

        //-----------------------------
        // offsetX
        //-----------------------------
        /**
         * @private
         */
        protected var _offsetX : Number = 0;

        [Bindable("offsetXChanged")]
        /**
         *
         *
         * @default 0
         */
        public function get offsetX() : Number
        {
            return _offsetX;
        }

        /**
         * @private
         */
        public function set offsetX(value : Number) : void
        {
            if (value == _offsetX)
            {
                return;
            }

            _offsetX = value;

            dispatchEvent(new Event("offsetXChanged"));
        }

        //-----------------------------
        // offsetY
        //-----------------------------
        /**
         * @private
         */
        protected var _offsetY : Number = 0;

        [Bindable("offsetYChanged")]
        /**
         *
         *
         * @default 0
         */
        public function get offsetY() : Number
        {
            return _offsetY;
        }

        /**
         * @private
         */
        public function set offsetY(value : Number) : void
        {
            if (value == _offsetY)
            {
                return;
            }

            _offsetY = value;

            dispatchEvent(new Event("offsetYChanged"));
        }

        //---------------------------------------------------------------------
        //
        //  Constructor
        //
        //---------------------------------------------------------------------
        /**
         *  Constructor
         */
        public function GraphControlLabelRenderer()
        {
            helperTextField = new UITextField();

            // Position off screen
            helperTextField.x = -10000;
            helperTextField.y = -10000;
            helperTextField.width = 10000;
            helperTextField.height = 10000;

            // Add so it inherits our text styling
            addChild(helperTextField);

            bitmap = new BitmapAsset(null);
            bitmap.x = 0;
            bitmap.y = 0;

            addChild(bitmap);
        }

        //---------------------------------------------------------------------
        //
        //  Overridden Methods
        //
        //---------------------------------------------------------------------
        /**
         * @inheritDoc
         */
        override protected function updateDisplayList(unscaledWidth : Number, unscaledHeight : Number) : void
        {
            super.updateDisplayList(unscaledWidth, unscaledHeight);

            if (direction == "horizontal")
            {
                var intervals : Array = intervalCollection.getIntervalsFor(parentGC.horizontalAxisOptions.visibleMinMax.start, parentGC.horizontalAxisOptions.visibleMinMax.end);

                // Clear out the current display.
                bitmap.bitmapData = new BitmapData(unscaledWidth, unscaledHeight, true, 0x00FFFFFF);
                bitmap.setActualSize(unscaledWidth, unscaledHeight);

                // Draw a frickin label for each interval
                for each (var interval : IInterval in intervals)
                {
                    helperTextField.text = intervalToStringGenerator.intervalToString(interval);

                    var x : Number = GraphControlUtil.getScreenforValue(new Point(interval.start, 0), parentGC).x;

                    var m : Matrix = new Matrix();
                    m.translate(x + offsetX, offsetY);

                    bitmap.bitmapData.draw(helperTextField, m);
                }
            }
            // TODO write code to be able to do vertical label layout
        }
    }
}
